/*
 * StatusBarDelegate.cpp  0.4.0 / Dec 05, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "StatusBarDelegate.h"

// StatusBarDelegate :: Protected Constructor. ---------------------------------

/*!
 * \brief Constructs new StatusBarDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the StatusBar java object
 */

StatusBarDelegate::StatusBarDelegate(JNIEnv *env, jobject obj)
  : ContainerDelegate(env, obj, new QStatusBar())
{
  qStatusBar()->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
  connectDirect(qStatusBar(), SIGNAL(messageChanged(const QString &)),
                SLOT(messageChangedSlot(const QString &)));
}

// StatusBarDelegate :: Native Calls. ------------------------------------------

/*!
 * \brief Displays the specified message
 *
 * \param env the JNIEnv pointer
 * \param message the message
 * \param timeout the message time out
 */
void StatusBarDelegate::showMessage(JNIEnv *env, jstring message,
                                    jint timeout)
{
  Q_ASSERT(env);
  Q_ASSERT(message);
  SWING_REENTRANT(showMessage, SWING_ENV_ARG, JSTRING_ARG(message),
                  JINT_ARG(timeout))
  qStatusBar()->showMessage(QStringAdapter(env, message), timeout);
}

/*!
 * \brief Clears status message
 *
 * \param env the JNIEnv pointer
 */
void StatusBarDelegate::clearMessage(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(clearMessage, SWING_ENV_ARG)
  qStatusBar()->clearMessage();
}

/*!
 * \brief Inserts temporary child.
 *
 * \param env the JNIEnv pointer
 * \param childDelegate the child delegate
 * \param index the child index
 */
void StatusBarDelegate::insertChild(JNIEnv *env, jlong childDelegate, jint index)
{
  Q_ASSERT(env);
  SWING_REENTRANT(insertChild, SWING_ENV_ARG, JLONG_ARG(childDelegate),
                  JINT_ARG(index))
  qStatusBar()->insertWidget(index, COMPONENT_CAST(childDelegate)->qWidget());
  COMPONENT_CAST(childDelegate)->setParentDelegate(this);
}

/*!
 * \brief Inserts permanent child.
 *
 * \param env the JNIEnv pointer
 * \param childDelegate the child delegate
 * \param index the child index
 */
void StatusBarDelegate::insertPermanentChild(JNIEnv *env, jlong childDelegate,
                                             jint index)
{
  Q_ASSERT(env);
  SWING_REENTRANT(insertPermanentChild, SWING_ENV_ARG, JLONG_ARG(childDelegate),
                  JINT_ARG(index))
  qStatusBar()->insertPermanentWidget(index,
                                      COMPONENT_CAST(childDelegate)->qWidget());
  COMPONENT_CAST(childDelegate)->setParentDelegate(this);
}

/*!
 * \brief Removes the specified child.
 *
 * \param env the JNIEnv pointer
 * \param childDelegate the child delegate
 */
void StatusBarDelegate::removeChild(JNIEnv *env, jlong childDelegate)
{
  Q_ASSERT(env);
  SWING_REENTRANT(removeChild, SWING_ENV_ARG, JLONG_ARG(childDelegate))
  qStatusBar()->removeWidget(COMPONENT_CAST(childDelegate)->qWidget());
  COMPONENT_CAST(childDelegate)->setParentDelegate(0);
}

/*!
 * \brief Sets whether or not the size grip is visible.
 *
 * \param env the JNIEnv pointer
 * \param enabled \c true if enabled
 */
void StatusBarDelegate::setSizeGripEnabled(JNIEnv *env, jboolean enabled)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setSizeGripEnabled, SWING_ENV_ARG, JBOOLEAN_ARG(enabled))
  qStatusBar()->setSizeGripEnabled(enabled);
}

// StatusBarDelegate :: Static Native Calls. -----------------------------------

/*!
 * \brief Initializes StatusBarDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the StatusBar java class
 *
 * \exception FatalError if failed
 */
void StatusBarDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_statusMessgeChangedMID);
  if (!INIT_UMID(statusMessgeChanged, cls, "(Ljava/lang/String;)V")) {
    FATAL_LOGGED_ERROR("StatusBarDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong StatusBarDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new StatusBarDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// StatusBarDelegate :: Native Callbacks. --------------------------------------

/*!
 * \brief Calls statusMessgeChanged method of the StatusBar java object.
 *
 * \param message the new status message
 */
void StatusBarDelegate::statusMessgeChanged(jstring message)
{
  jniObject()->callVoidMethod(sm_statusMessgeChangedMID, message);
}

// StatusBarDelegate :: Protected Member Function. -----------------------------

/*!
 * \brief Message changend slot.
 *
 * \param message the status message
 */
void StatusBarDelegate::messageChangedSlot(const QString &message)
{ 
  if (message.isNull()) {
    statusMessgeChanged(0);
  } else {
    statusMessgeChanged(SwingString::toJString(message));
  }
}

// StatusBarDelegate :: Overridden Member Function. ----------------------------

/*!
 * \inheritDoc
 */
void StatusBarDelegate::setParentDelegate(ContainerDelegate *parentDelegate)
{
  ContainerDelegate::setParentDelegate(parentDelegate);
  if (parentDelegate) {
     // QSizeGrip bug workaround // TODO: check
    bool sizeGripEnabled = qStatusBar()->isSizeGripEnabled();
    qStatusBar()->setSizeGripEnabled(!sizeGripEnabled);
    qStatusBar()->setSizeGripEnabled(sizeGripEnabled);
  }
}

// StatusBarDelegate :: Private Static Data Member. ----------------------------

jmethodID StatusBarDelegate::sm_statusMessgeChangedMID = 0;
